package study.nosql.redis.consumer;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.data.redis.core.BoundListOperations;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

/**
 * list 实现队列
 * （1）while(true)，实现长轮训！！！
 * （2）自定义线程需要对异常进行处理: 自定义线程中，对异常不 catch 会造成线程终止执行！！！
 * （4）区分启动线程和业务线程
 * （5）队列值空判断
 */
@Slf4j
@Component
public class ListQueConsumer implements CommandLineRunner {

    @Autowired
    private BoundListOperations<String, String> listQueue;

    private ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

    @Override
    public void run(String... args) throws Exception {
        //
        Thread t = ThreadUtil.newThread(() -> {
            while (true) {
                try {
                    // 休眠
                    ThreadUtil.sleep(5 * 1000);
                    // 获取队列值
                    String value = listQueue.rightPop();
                    if (StrUtil.isEmpty(value)) {
                        log.warn(">>>>>> 队列为空");
                        continue;
                    }
                    // 处理队列值
                    log.info(">>>>>> 处理队列值 {}", value);
                } catch (Exception ex) {
                    // print exception
                    log.error("", ex);
                }
            }
        }, "Queue-List-Consumer");
        t.start();


        //
//        scheduler.scheduleWithFixedDelay(() -> {
//            log.info("sadfasdfsad");
//            // 阻塞3秒钟
//            consumer3();
//        }, 1, 1, TimeUnit.SECONDS);
    }

    /**
     *
     */
    public void consumer3() {
        String str = listQueue.rightPop(Duration.ofMillis(5000));
        //
        if (StrUtil.isEmpty(str)) {
            log.warn(">>>>>> 队列为空");
            return;
        }
        //
        try {
            log.info(">>>>>>>>>>> 获取队列值 {}", str);
        } catch (Exception ex) {
            // wrap exception
            throw new RuntimeException("", ex);
        }
    }
}
